#include "dyn_roots_sta.h"

STA::STA(Maps1D& map,
         double init,
         double para,
         const double tol,
         const int Nmax)
    :map1d(map)
{
    setInitialValue(init);
    setLambda(para);
    setTolerance(tol);
    setMaxIterations(Nmax);
}

int STA::solve()
{
    // We start the clock
    start = clock();

    // We initialize the return variables and return code.
    int returnCode(1);
    int orbitFound(0);
    root = initialValue;
    fixedPoints.set_size(map1d.getPeriod());

    arma::colvec C = arma::colvec(2);
    C << 1 << arma::endr
      << -1 << arma::endr;

    for (int j=0;j<2;j++)
    {
        for (int i=0;i<maxIterations;i++)
        {
            double dx1 = lambda*C(j)*(map1d.iterate(root,map1d.getPeriod())-root);

            root += dx1;

            if (fabs(dx1) < tolerance)
            {
                orbitFound = 1;
                break;
            }
        }

        if (orbitFound)
        {
            fixedPoints(0) = root;

            for (int k=1;k<map1d.getPeriod();k++)
            {
                double transient = map1d.iterate(fixedPoints(k-1),1);

                for (int i=0;i<maxIterations;i++)
                {
                    double dx1 = lambda*C(j)*(map1d.iterate(transient,map1d.getPeriod())-transient);
                    transient += dx1;

                    if (fabs(dx1) < tolerance)
                    {
                        fixedPoints(k) = transient;
                        break;
                    }
                }
            }
            returnCode = 0;
            break;
        }
    return returnCode;
    }
    // We stop the clock
    end = clock();

    processorTime = ((double) (end-start))/ CLOCKS_PER_SEC;
    return returnCode;
}
